#!/bin/bash

# 金牛座表结构生成工具
# 用于获取表结构信息并生成TypeScript类型定义和MD文档
# @author 生命线项目组
# @date 2024-03-27

# 脚本所在目录
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# 加载环境配置文件
CONFIG_FILE="$SCRIPT_DIR/env.config"
if [ ! -f "$CONFIG_FILE" ]; then
  echo "错误: 找不到配置文件 $CONFIG_FILE"
  exit 1
fi

source "$CONFIG_FILE"
echo "已加载配置文件: $CONFIG_FILE"

# 输出目录
OUTPUT_DIR="$OUTPUT_BASE_DIR/docs/api"
TYPE_OUTPUT_PATH="$OUTPUT_DIR/types.ts"

# 创建输出目录
mkdir -p "$OUTPUT_DIR"
echo "创建目录: $OUTPUT_DIR"

# 获取token
echo "正在获取token..."
TOKEN_RESPONSE=$(curl -s -X POST "$AUTO_API_BASE_URL/get_token" \
  -H "Content-Type: application/json" \
  -d "{\"id\": \"$PROJECT_ID\"}")

TOKEN=$(echo $TOKEN_RESPONSE | grep -o '"token":"[^"]*"' | cut -d'"' -f4)

if [ -z "$TOKEN" ]; then
  echo "获取token失败: $TOKEN_RESPONSE"
  exit 1
fi

echo "token获取成功!"

# 表名列表
TABLE_NAMES=(
  "ods_ng_pipline_attr"
  "ods_ng_pipeline_point_attr"
  "ods_p_station_attr"
  "ods_ng_resident_user_attr"
  "ods_lpg_deliver_flow_log"
  "ods_ng_pipeline_inspection_point_attr"
  "ods_ng_pipeline_inspection_attr"
  "ods_p_iot_device_attr"
  "ods_ng_pipeline_inspection_log"
  "ods_ng_resident_sc_log"
  "ods_ng_resident_sc_hd_log"
  "ods_lpg_deliver_order_sc_log"
  "ods_lpg_deliver_order_hd_log"
  "ods_lpg_hd_attr"
  "ods_D_iot_device_alarm_log"
  "ods_p_iot_monitor_log"
  "ods_D_emer_team_supply_attr"
)

# 获取表列表
echo "正在获取数据库 $SCHEMA_NAME 中的表..."
TABLE_LIST_RESPONSE=$(curl -s -X POST "$AUTO_API_BASE_URL/findby" \
  -H "Content-Type: application/json" \
  -H "x-token: $TOKEN" \
  -d "{\"tablelist\": {\"tableSchema\": \"$SCHEMA_NAME\"}}")

# 此处需要根据实际返回数据格式解析表信息
echo "获取表列表成功，开始处理..."

# 初始化TypeScript类型定义文件内容
cat > "$TYPE_OUTPUT_PATH" << EOL
/**
 * 自动生成的表接口定义文件
 * 生成时间: $(date)
 */

EOL

# 处理每个表
for tableName in "${TABLE_NAMES[@]}"; do
  echo "正在处理表: $tableName"
  
  # 获取表字段信息
  COLUMNS_RESPONSE=$(curl -s -X POST "$AUTO_API_BASE_URL/findby" \
    -H "Content-Type: application/json" \
    -H "x-token: $TOKEN" \
    -d "{\"tablecols\": {\"tableSchema\": \"$SCHEMA_NAME\", \"tableName\": \"$tableName\"}}")
  
  # 保存字段信息到临时文件
  TEMP_COLUMNS_FILE="/tmp/columns_$tableName.json"
  echo "$COLUMNS_RESPONSE" > "$TEMP_COLUMNS_FILE"
  
  # 提取表注释（这里假设表信息中有tableComment字段）
  TABLE_COMMENT=$(echo "$TABLE_LIST_RESPONSE" | grep -o "\"$tableName\".*\"tableComment\":\"[^\"]*\"" | grep -o "\"tableComment\":\"[^\"]*\"" | cut -d'"' -f4)
  
  if [ -z "$TABLE_COMMENT" ]; then
    TABLE_COMMENT="$tableName"
  fi
  
  # 生成接口名称（转换为驼峰命名）
  INTERFACE_NAME=""
  IFS='_' read -ra PARTS <<< "$tableName"
  for part in "${PARTS[@]}"; do
    INTERFACE_NAME+="$(tr '[:lower:]' '[:upper:]' <<< ${part:0:1})${part:1}"
  done
  
  # 生成TypeScript接口定义
  echo "/**
 * $TABLE_COMMENT
 */
export interface I$INTERFACE_NAME {" >> "$TYPE_OUTPUT_PATH"
  
  # 使用jq处理字段（如果有jq）
  if command -v jq &> /dev/null; then
    jq -c '.[]' "$TEMP_COLUMNS_FILE" | while read -r column; do
      COLUMN_NAME=$(echo "$column" | jq -r '.columnName')
      COLUMN_TYPE=$(echo "$column" | jq -r '.columnType')
      COLUMN_COMMENT=$(echo "$column" | jq -r '.columnComment')
      COLUMN_KEY=$(echo "$column" | jq -r '.columnKey')
      
      # 转换为驼峰命名
      CAMEL_NAME=""
      IFS='_' read -ra PARTS <<< "$COLUMN_NAME"
      for i in "${!PARTS[@]}"; do
        if [ "$i" -eq 0 ]; then
          CAMEL_NAME+="${PARTS[$i]}"
        else
          CAMEL_NAME+="$(tr '[:lower:]' '[:upper:]' <<< ${PARTS[$i]:0:1})${PARTS[$i]:1}"
        fi
      done
      
      # 确定TypeScript类型
      TS_TYPE="any"
      if [[ "$COLUMN_TYPE" == *"varchar"* || "$COLUMN_TYPE" == *"char"* || "$COLUMN_TYPE" == *"text"* ]]; then
        TS_TYPE="string"
      elif [[ "$COLUMN_TYPE" == *"int"* || "$COLUMN_TYPE" == *"float"* || "$COLUMN_TYPE" == *"double"* || "$COLUMN_TYPE" == *"decimal"* ]]; then
        TS_TYPE="number"
      elif [[ "$COLUMN_TYPE" == *"datetime"* || "$COLUMN_TYPE" == *"timestamp"* || "$COLUMN_TYPE" == *"date"* ]]; then
        TS_TYPE="Date"
      fi
      
      # 添加字段定义
      OPTIONAL=""
      if [ "$COLUMN_KEY" != "PRI" ]; then
        OPTIONAL="?"
      fi
      
      echo "  /** $COLUMN_COMMENT */
  $CAMEL_NAME$OPTIONAL: $TS_TYPE;" >> "$TYPE_OUTPUT_PATH"
    done
  else
    # 简单解析JSON（如果没有jq）
    # 这部分代码在实际环境中可能需要调整
    grep -o "\"columnName\":\"[^\"]*\".*\"columnType\":\"[^\"]*\".*\"columnComment\":\"[^\"]*\".*\"columnKey\":\"[^\"]*\"" "$TEMP_COLUMNS_FILE" | while read -r columnInfo; do
      COLUMN_NAME=$(echo "$columnInfo" | grep -o "\"columnName\":\"[^\"]*\"" | cut -d'"' -f4)
      COLUMN_TYPE=$(echo "$columnInfo" | grep -o "\"columnType\":\"[^\"]*\"" | cut -d'"' -f4)
      COLUMN_COMMENT=$(echo "$columnInfo" | grep -o "\"columnComment\":\"[^\"]*\"" | cut -d'"' -f4)
      COLUMN_KEY=$(echo "$columnInfo" | grep -o "\"columnKey\":\"[^\"]*\"" | cut -d'"' -f4)
      
      # 转换为驼峰命名
      CAMEL_NAME=""
      IFS='_' read -ra PARTS <<< "$COLUMN_NAME"
      for i in "${!PARTS[@]}"; do
        if [ "$i" -eq 0 ]; then
          CAMEL_NAME+="${PARTS[$i]}"
        else
          CAMEL_NAME+="$(tr '[:lower:]' '[:upper:]' <<< ${PARTS[$i]:0:1})${PARTS[$i]:1}"
        fi
      done
      
      # 确定TypeScript类型
      TS_TYPE="any"
      if [[ "$COLUMN_TYPE" == *"varchar"* || "$COLUMN_TYPE" == *"char"* || "$COLUMN_TYPE" == *"text"* ]]; then
        TS_TYPE="string"
      elif [[ "$COLUMN_TYPE" == *"int"* || "$COLUMN_TYPE" == *"float"* || "$COLUMN_TYPE" == *"double"* || "$COLUMN_TYPE" == *"decimal"* ]]; then
        TS_TYPE="number"
      elif [[ "$COLUMN_TYPE" == *"datetime"* || "$COLUMN_TYPE" == *"timestamp"* || "$COLUMN_TYPE" == *"date"* ]]; then
        TS_TYPE="Date"
      fi
      
      # 添加字段定义
      OPTIONAL=""
      if [ "$COLUMN_KEY" != "PRI" ]; then
        OPTIONAL="?"
      fi
      
      echo "  /** $COLUMN_COMMENT */
  $CAMEL_NAME$OPTIONAL: $TS_TYPE;" >> "$TYPE_OUTPUT_PATH"
    done
  fi
  
  # 完成接口定义
  echo "}" >> "$TYPE_OUTPUT_PATH"
  echo "" >> "$TYPE_OUTPUT_PATH"
  
  # 生成MD文档
  MD_PATH="$OUTPUT_DIR/$tableName.md"
  
  # 表头
  cat > "$MD_PATH" << EOL
# $TABLE_COMMENT 接口文档

## 数据结构

### 字段说明

| 字段名 | 类型 | 说明 | 是否必填 |
|-------|------|-----|---------|
EOL
  
  # 添加字段表格
  if command -v jq &> /dev/null; then
    jq -c '.[]' "$TEMP_COLUMNS_FILE" | while read -r column; do
      COLUMN_NAME=$(echo "$column" | jq -r '.columnName')
      COLUMN_TYPE=$(echo "$column" | jq -r '.columnType')
      COLUMN_COMMENT=$(echo "$column" | jq -r '.columnComment')
      COLUMN_KEY=$(echo "$column" | jq -r '.columnKey')
      
      IS_REQUIRED="否"
      if [ "$COLUMN_KEY" == "PRI" ]; then
        IS_REQUIRED="是"
      fi
      
      echo "| $COLUMN_NAME | $COLUMN_TYPE | $COLUMN_COMMENT | $IS_REQUIRED |" >> "$MD_PATH"
    done
  else
    grep -o "\"columnName\":\"[^\"]*\".*\"columnType\":\"[^\"]*\".*\"columnComment\":\"[^\"]*\".*\"columnKey\":\"[^\"]*\"" "$TEMP_COLUMNS_FILE" | while read -r columnInfo; do
      COLUMN_NAME=$(echo "$columnInfo" | grep -o "\"columnName\":\"[^\"]*\"" | cut -d'"' -f4)
      COLUMN_TYPE=$(echo "$columnInfo" | grep -o "\"columnType\":\"[^\"]*\"" | cut -d'"' -f4)
      COLUMN_COMMENT=$(echo "$columnInfo" | grep -o "\"columnComment\":\"[^\"]*\"" | cut -d'"' -f4)
      COLUMN_KEY=$(echo "$columnInfo" | grep -o "\"columnKey\":\"[^\"]*\"" | cut -d'"' -f4)
      
      IS_REQUIRED="否"
      if [ "$COLUMN_KEY" == "PRI" ]; then
        IS_REQUIRED="是"
      fi
      
      echo "| $COLUMN_NAME | $COLUMN_TYPE | $COLUMN_COMMENT | $IS_REQUIRED |" >> "$MD_PATH"
    done
  fi
  
  # 添加TypeScript类型定义
  cat >> "$MD_PATH" << EOL

## TypeScript类型定义

\`\`\`typescript
/**
 * $TABLE_COMMENT
 */
export interface I$INTERFACE_NAME {
EOL

  # 添加字段定义到MD
  if command -v jq &> /dev/null; then
    jq -c '.[]' "$TEMP_COLUMNS_FILE" | while read -r column; do
      COLUMN_NAME=$(echo "$column" | jq -r '.columnName')
      COLUMN_TYPE=$(echo "$column" | jq -r '.columnType')
      COLUMN_COMMENT=$(echo "$column" | jq -r '.columnComment')
      COLUMN_KEY=$(echo "$column" | jq -r '.columnKey')
      
      # 转换为驼峰命名
      CAMEL_NAME=""
      IFS='_' read -ra PARTS <<< "$COLUMN_NAME"
      for i in "${!PARTS[@]}"; do
        if [ "$i" -eq 0 ]; then
          CAMEL_NAME+="${PARTS[$i]}"
        else
          CAMEL_NAME+="$(tr '[:lower:]' '[:upper:]' <<< ${PARTS[$i]:0:1})${PARTS[$i]:1}"
        fi
      done
      
      # 确定TypeScript类型
      TS_TYPE="any"
      if [[ "$COLUMN_TYPE" == *"varchar"* || "$COLUMN_TYPE" == *"char"* || "$COLUMN_TYPE" == *"text"* ]]; then
        TS_TYPE="string"
      elif [[ "$COLUMN_TYPE" == *"int"* || "$COLUMN_TYPE" == *"float"* || "$COLUMN_TYPE" == *"double"* || "$COLUMN_TYPE" == *"decimal"* ]]; then
        TS_TYPE="number"
      elif [[ "$COLUMN_TYPE" == *"datetime"* || "$COLUMN_TYPE" == *"timestamp"* || "$COLUMN_TYPE" == *"date"* ]]; then
        TS_TYPE="Date"
      fi
      
      # 添加字段定义
      OPTIONAL=""
      if [ "$COLUMN_KEY" != "PRI" ]; then
        OPTIONAL="?"
      fi
      
      echo "  /** $COLUMN_COMMENT */
  $CAMEL_NAME$OPTIONAL: $TS_TYPE;" >> "$MD_PATH"
    done
  fi
  
  # 完成TypeScript接口定义
  echo "}" >> "$MD_PATH"
  echo "\`\`\`" >> "$MD_PATH"
  
  # 添加CRUD操作示例
  cat >> "$MD_PATH" << EOL

## 接口使用示例

### 查询数据

#### 分页查询

\`\`\`typescript
import { autoPost } from "@/utils/http";

// 分页查询
async function query${tableName}List(page: number = 1, pageSize: number = 10) {
  return await autoPost("/query", {
    "${tableName}": {
      page,
      pagesize: pageSize,
      opts: {
        rsstyle: "camel"  // 返回结果使用驼峰命名
      }
    }
  });
}
\`\`\`

#### 条件查询

\`\`\`typescript
// 条件查询
async function query${tableName}ByCondition(condition: any) {
  return await autoPost("/query", {
    "${tableName}": {
      where: condition,
      opts: {
        rsstyle: "camel"
      }
    }
  });
}

// 使用示例
const result = await query${tableName}ByCondition(["=", "id", 1001]);
\`\`\`

### 新增数据

\`\`\`typescript
async function create${tableName}(data: any) {
  return await autoPost("/crud/create", {
    "${tableName}": {
      ...data,
      opts: {
        // 如果需要自动生成主键
        // pk: "id",
        // genkey: true
      }
    }
  });
}
\`\`\`

### 更新数据

\`\`\`typescript
async function update${tableName}(data: any, whereCondition: any) {
  return await autoPost("/crud/update", {
    "${tableName}": {
      ...data,
      where: whereCondition
    }
  });
}

// 使用示例
const result = await update${tableName}(
  { name: "新名称" },
  { id: 1001 }
);
\`\`\`

### 删除数据

\`\`\`typescript
async function delete${tableName}(whereCondition: any) {
  return await autoPost("/crud/delete", {
    "${tableName}": whereCondition
  });
}

// 使用示例
const result = await delete${tableName}({ id: 1001 });
\`\`\`

### 导入导出

#### 导出CSV

\`\`\`typescript
async function export${tableName}ToCsv(data: any[]) {
  // 从columns中提取字段名和注释
  const header = "字段1,注释1,字段2,注释2"; // 实际应该从字段信息构建
  
  return await autoPost("/data_to_csv", {
    header: header,
    rows: data
  });
}
\`\`\`

#### 导入CSV

\`\`\`typescript
// 通过表单提交CSV文件
// 需要使用FormData对象
async function import${tableName}FromCsv(file: File) {
  const formData = new FormData();
  formData.append("table", "${tableName}");
  formData.append("header", "字段1,注释1,字段2,注释2"); // 实际应该从字段信息构建
  formData.append("file", file);
  
  // 使用fetch API提交
  return await fetch("${AUTO_API_BASE_URL}/import_csv", {
    method: "POST",
    body: formData,
    headers: {
      "x-token": localStorage.getItem("x-token") || ""
    }
  }).then(res => res.json());
}
\`\`\`
EOL
  
  # 删除临时文件
  rm -f "$TEMP_COLUMNS_FILE"
  
  echo "生成MD文档: $MD_PATH"
done

echo "生成类型定义文件: $TYPE_OUTPUT_PATH"
echo "全部文档生成完成!" 